home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
source
/
zendisk2
/
lst14-16.asm
< prev
next >
Wrap
Assembly Source File
|
1990-02-15
|
5KB
|
189 lines
;
; *** Listing 14-16 ***
;
; Demonstrates the use of a jump table to branch into
; in-line code consisting of repeated code blocks of
; varying lengths. Branches out of the in-line code with
; 1-byte displacements at both ends of the in-line code,
; for improved speed.
;
; Searches up to N bytes of a zero- terminated string for
; a character.
;
jmp Skip
TestString label byte
db 'This is a string containing the letter '
db 'z but not containing capital q', 0
;
; Searches a zero-terminated string for a character.
; Searches until a match is found, the terminating zero
; is found, or the specified number of characters has been
; checked.
;
; Input:
; AL = character to search for
; BX = maximum # of characters to search. Must be
; less than or equal to MAX_SEARCH_LENGTH
; DS:SI = string to search
;
; Output:
; SI = pointer to character, or 0 if character not
; found
;
; Registers altered: AX, BX, SI
;
; Direction flag cleared
;
; Note: Don't pass a string starting at offset 0, since a
; match there couldn't be distinguished from a failure
; to match.
;
MAX_SEARCH_LENGTH equ 80 ;longest supported search
; length
;
; Macro to create SearchTable entries.
;
MAKE_CHECK_CHAR_LABEL macro NUMBER
dw CheckChar&NUMBER&
endm
;
; Macro to create in-line code to search 1 character.
; Gives the code block a unique label according to NUMBER.
; Each conditional branch uses the shortest possible jump
; sequence to reach NoMatch and MatchFound.
;
CHECK_CHAR macro NUMBER
local CheckMatch, Continue
CheckChar&NUMBER&:
lodsb ;get the character
and al,al ;done if terminating zero
;
; Assemble a single conditional jump if it'll reach, or
; a conditional jump around an unconditional jump if the
; 1-byte displacement of a conditional jump won't reach.
;
if ($+2-NoMatch) le 128
jz NoMatch
else
jnz CheckMatch
jmp NoMatch
endif
CheckMatch:
cmp ah,al ;done if matches search character
;
; Again, assemble shortest possible jump sequence.
;
if ($+2-MatchFound) le 128
jz MatchFound
else
jnz Continue
jmp MatchFound
endif
Continue:
endm
;
; Macro to create in-line code to search 1 character.
; Gives the code block a unique label according to NUMBER.
; All branches use a 1-byte displacement to branch to
; NoMatch2 and MatchFound2.
;
CHECK_CHAR2 macro NUMBER
CheckChar&NUMBER&:
lodsb ;get the character
and al,al ;done if terminating zero
jz NoMatch2
cmp ah,al ;done if matches search character
jz MatchFound2
endm
;
; Table of in-line code entry points for maximum search
; lengths of 0 through 80.
;
SearchTable label word
dw NoMatch ;we never match on a
; maximum length of 0
BLOCK_NUMBER=MAX_SEARCH_LENGTH-1
rept MAX_SEARCH_LENGTH
MAKE_CHECK_CHAR_LABEL %BLOCK_NUMBER
BLOCK_NUMBER=BLOCK_NUMBER-1
endm
;
SearchNBytes proc near
mov ah,al ;we'll need AL for LODSB
cmp bx,MAX_SEARCH_LENGTH
ja NoMatch ;if the maximum length's
; too long for the in-line
; code, return a no-match
; status
shl bx,1 ;*2 to look up in word-sized
; table
jmp [SearchTable+bx] ;branch into the in-line
; code to do the search
;
; No match was found.
;
NoMatch:
sub si,si ;return no-match status
ret
;
; A match was found.
;
MatchFound:
dec si ;point back to matching
; location
ret
;
; This is the in-line code that actually does the search.
; Each repetition is uniquely labelled, with labels
; CheckChar0 through CheckChar79.
;
BLOCK_NUMBER=0
;
; These in-line code blocks use 1-byte displacements
; whenever possible to branch backward; otherwise 2-byte
; displacements are used to branch backwards, with
; conditional jumps around unconditional jumps.
;
rept MAX_SEARCH_LENGTH-14
CHECK_CHAR %BLOCK_NUMBER
BLOCK_NUMBER=BLOCK_NUMBER+1
endm
;
; These in-line code blocks use 1-byte displacements to
; branch forward.
;
rept 14
CHECK_CHAR2 %BLOCK_NUMBER
BLOCK_NUMBER=BLOCK_NUMBER+1
endm
;
; If we make it here, we haven't found the character.
;
NoMatch2:
sub si,si ;return no-match status
ret
;
; A match was found.
;
MatchFound2:
dec si ;point back to matching
; location
ret
SearchNBytes endp
;
Skip:
call ZTimerOn
mov al,'Q'
mov bx,20 ;search up to the
mov si,offset TestString ; first 20 bytes of
call SearchNBytes ; TestString for 'Q'
mov al,'z'
mov bx,80 ;search up to the
mov si,offset TestString ; first 80 bytes of
call SearchNBytes ; TestString for 'z'
mov al,'a'
mov bx,10 ;search up to the
mov si,offset TestString ; first 10 bytes of
call SearchNBytes ; TestString for 'a'
call ZTimerOff